// NewTrainingFramework.cpp : Defines the entry point for the console application.
//


#include "stdafx.h"
#include "../Utilities/utilities.h" // if you use STL, please include this line AFTER all other include
#include "Vertex.h"
#include "Shaders.h"
#include <conio.h>
#include "Globals.h"
#include "Camera.h"
#include "object.h"
#include "Skydome.h"
#include "ReflectingObject.h"
#include "Terrain.h"
#include "IlluminatedObject.h"
#include "UVDispObject.h"
#include "ParticleSystem.h"
Shaders myShaders;
Camera camera;
Matrix* mvpMatrix;
IlluminatedObject* object;
IlluminatedObject* iobject;
Skydome* skydome;
Terrain* terrain;
ReflectingObject* robject;
UVDispObject* uvobject;
ParticleSystem* ps;
using namespace std;
void CleanUp()
{
	delete object;
	delete robject;
	delete skydome;
}

int Init ( ESContext *esContext )
{
	Vector3 lightPosition(30, 20, 50);
	//m.Load("Marine.nfg", "Marine.tga");
	glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
	camera.setFOV(Vector3(0, 100, 200), Vector3 (0, 1, 0), Vector3(0, 0, 0), 1.0f, (float)Globals::screenWidth / Globals::screenHeight,1, 100000);
	ps = new ParticleSystem;
	ps->Init(2);
	//model->moveTo(Vector3(0, 0, 0)); 
	terrain = new Terrain;
	terrain->Load(Vector3(64, 0, 64),
					"../Resources/Model_Texture/heightmap.raw",
					"../Resources/Model_Texture/Terrain_blendmap_2.tga",
					"../Resources/Model_Texture/Dirt.tga",
					"../Resources/Model_Texture/Grass.tga",
					"../Resources/Model_Texture/Rock.tga",
					"../Resources/Model_Texture/NormalMap.tga");
	object = new IlluminatedObject;
	object->Load("../Resources/Model_Texture/Woman2.nfg", "../Resources/Model_Texture/Woman2.tga",
					"../Resources/Model_Texture/NormalMap.tga", lightPosition);
	//object->moveTo(Vector3(-10, 0, 10));

	

	skydome = new Skydome;
	
	skydome->Load(	"../Resources/Model_Texture/SkyBox.nfg", 
					"../Resources/Model_Texture/alpine_right.tga", 
					"../Resources/Model_Texture/alpine_left.tga",
					"../Resources/Model_Texture/alpine_top.tga",
					"../Resources/Model_Texture/Dirt.tga", 
					"../Resources/Model_Texture/alpine_front.tga", 
					"../Resources/Model_Texture/alpine_back.tga");
	skydome->Scale(10000, 10000, 10000);

	robject = new ReflectingObject;
	robject->Load("../Resources/Model_Texture/Bila.nfg", skydome);

	iobject = new IlluminatedObject;
	iobject->Load("../Resources/Model_Texture/Bila.nfg", "../Resources/Model_Texture/Rock.tga",	"../Resources/Model_Texture/NormalMap.tga" , lightPosition);
	iobject->Place(-50, -20, 20);
	object->Scale(10, 10, 10);
	object->setLightPosition(lightPosition);

	uvobject = new UVDispObject;
	uvobject->Load("../Resources/Model_Texture/fire3.tga",
				   "../Resources/Model_Texture/DisplacementMap.tga",
				   "../Resources/Model_Texture/fire_mask.tga",
				   "../Resources/Model_Texture/fire.nfg");
	uvobject->Scale(10, 10, 10);
	uvobject->Place(100, 0, 0);
	return 0;
}

void Draw ( ESContext *esContext )
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0.0f, 0.5f, 0.5f, 0.0f );
	glEnable(GL_DEPTH_TEST);


	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	object->Draw(esContext, &camera);
	iobject->Draw(esContext, &camera);
	robject->Draw(esContext, &camera);
	terrain->Draw(esContext, &camera);
	skydome->Draw(esContext, &camera);
	

	ps->Draw(&camera);

	uvobject->Draw(esContext, &camera);
	eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
}

void Update ( ESContext *esContext, float deltaTime )
{
	uvobject->Update(esContext, deltaTime);
	ps->Update(deltaTime);
}

void Key ( ESContext *esContext, unsigned char key, bool bIsPressed)
{
	if (bIsPressed)
	{
		switch (key)
		{
		case 'W':
			camera.moveForward();break;
		case 'S':
			camera.moveBackward();break;
		case 'A':
			camera.moveLeft();break;
		case 'D':
			camera.moveRight();break;
		case 'J':
			camera.RotateLeft();break;
		case 'L':
			camera.RotateRight();break;
		case 'I':
			camera.RotateUp();break;
		case 'K':
			camera.RotateDown();break;
			
		case 37:
			iobject->RotateLeft();break;
		case 39:
			iobject->RotateRight();break;
		case 38:
			iobject->RotateUp();break;
		case 40:
			iobject->RotateDown();break;
		
		case 96 + 8:
			iobject->moveForward();break;
		case 96 + 2:
			iobject->moveBackward();break;
		case 96 + 4:
			iobject->moveLeft();break;
		case 96 + 6:
			iobject->moveRight();break;

		case 'P':
			ps->Play(); break;
		case 'Z':
			ps->Stop(); break;
		default: 
			{
				//CleanUp();
				exit(0);
			} break;
		}
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	//identifying memory leaks
	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

	ESContext esContext;

    esInitContext ( &esContext );

	esCreateWindow ( &esContext, "Hello Triangle", Globals::screenWidth, Globals::screenHeight, ES_WINDOW_RGB | ES_WINDOW_DEPTH);

	if ( Init ( &esContext ) != 0 )
		return 0;

	esRegisterDrawFunc ( &esContext, Draw );
	esRegisterUpdateFunc ( &esContext, Update );
	esRegisterKeyFunc ( &esContext, Key);

	esMainLoop ( &esContext );

	//releasing OpenGL resources
	CleanUp();

	printf("Press any key...\n");
	_getch();

	return 0;
}

